
import pytest
from common import log
from common.sql import MysqlAuto  # 修改导入方式
from po.event import Event
from settings import DBSql, ENV, SELENIUM_IMPLICIT_WAIT
from common.open import OpenService
import os
import time
import allure
from config.conf import ALLURE_IMG_DIR


@pytest.fixture(scope="function")
def login():
    driver = OpenService.get_chrome_driver()
    log.debug("打开浏览器")
    driver.get(ENV.url)
    driver.maximize_window()
    log.debug("最大化浏览器")
    # 隐式等待（可配置）
    driver.implicitly_wait(SELENIUM_IMPLICIT_WAIT)
    # 初始化数据
    sql = MysqlAuto()  # 实例化MysqlAuto类
    sql.execute(DBSql.sql_list)
    Event().event_login(driver, ENV.username, ENV.password)
    yield driver  # 返回driver yield之前的内容setup_class，yield之后是teardown_class()
    driver.quit()
    log.debug("关闭浏览器")


@pytest.fixture(scope="class")  # 改为 class 级别
def open_page():
    driver = OpenService.get_chrome_driver()
    log.debug("打开浏览器")
    driver.get(ENV.url)
    driver.maximize_window()
    log.debug("最大化浏览器")
    # 隐式等待（可配置）
    driver.implicitly_wait(SELENIUM_IMPLICIT_WAIT)
    sql = MysqlAuto()  # 实例化MysqlAuto类
    sql.execute(DBSql.sql_list)  # 初始化数据 得清除 不然拿着已注册的再跑用例就错误了
    yield driver  # 注册不需要初始化数据，所以移除了 sql 相关代码
    driver.quit()
    log.debug("关闭浏览器")


# ------------------------ Allure 截图&附件 ------------------------
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
    """测试执行结果钩子：用例失败时自动截图并附加到 Allure 报告"""
    outcome = yield
    rep = outcome.get_result()

    # 仅在测试函数执行阶段(call)且结果为失败时处理
    if rep.when == "call" and rep.failed:
        driver = None
        # 优先通过已知 fixture 名称获取 driver
        for key in ("open_page", "login"):
            driver = item.funcargs.get(key)
            if driver:
                break
        # 容错：遍历 funcargs，寻找具有 save_screenshot 方法的对象
        if not driver:
            for val in item.funcargs.values():
                if hasattr(val, "save_screenshot"):
                    driver = val
                    break
        # 如果拿到了 driver，则进行截图并附加
        if driver:
            if not os.path.exists(ALLURE_IMG_DIR):
                os.makedirs(ALLURE_IMG_DIR, exist_ok=True)
            file_name = f"{item.name}_{int(time.time())}.png"
            file_path = os.path.join(ALLURE_IMG_DIR, file_name)
            try:
                driver.save_screenshot(file_path)
                allure.attach.file(file_path, name="失败截图", attachment_type=allure.attachment_type.PNG)
            except Exception as e:  # 捕获 WebDriver 已关闭或页面变动导致的异常
                log.error(f"截图失败: {e}")
                # 不抛出异常，避免 pytest INTERNALERROR